import 'dart:io';
import 'dart:math';

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'dart:async';

import 'package:flutter/services.dart';
import 'package:text_pixel/text_pixel.dart';

import 'bean/text_bean.dart';
import 'ui/painter/color_painter.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        // This is the theme of your application.
        //
        // TRY THIS: Try running your application with "flutter run". You'll see
        // the application has a purple toolbar. Then, without quitting the app,
        // try changing the seedColor in the colorScheme below to Colors.green
        // and then invoke "hot reload" (save your changes or press the "hot
        // reload" button in a Flutter-supported IDE, or press "r" if you used
        // the command line to start the app).
        //
        // Notice that the counter didn't reset back to zero; the application
        // state is not lost during the reload. To reset the state, use hot
        // restart instead.
        //
        // This works for code too, not just values: Most code changes can be
        // tested with just a hot reload.
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      debugShowCheckedModeBanner: false,
      home: const HomePage(),
    );
  }
}


class HomePage extends StatefulWidget {
  const HomePage({super.key});

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  String _platformVersion = 'Unknown';
  final _textPixelPlugin = TextPixel();
  late TextEditingController _textEditingController;
  late ColorNotifier _colorNotifier;

  @override
  void initState() {
    super.initState();
    initPlatformState();
    _textEditingController = TextEditingController();
    _textEditingController.addListener(_onInput);
    _colorNotifier = ColorNotifier();
    _fontSizes.clear();
    for(int i = 8; i <= 66; i+=2){
      _fontSizes.add(i);
    }
  }

  // Platform messages are asynchronous, so we initialize in an async method.
  Future<void> initPlatformState() async {
    String platformVersion;
    // Platform messages may fail, so we use a try/catch PlatformException.
    // We also handle the message potentially returning null.
    try {
      platformVersion =
          await _textPixelPlugin.getPlatformVersion() ?? 'Unknown platform version';
    } on PlatformException {
      platformVersion = 'Failed to get platform version.';
    }

    // If the widget was removed from the tree while the asynchronous platform
    // message was in flight, we want to discard the reply rather than calling
    // setState to update our non-existent appearance.
    if (!mounted) return;

    setState(() {
      _platformVersion = platformVersion;
    });
  }

  final List<TextBean> _textList = [];
  final Color _color = const Color(0xFFFF0000);

  String _lastText = "";
  void _onInput(){
    if (Platform.isIOS) {
      if (_textEditingController.value.isComposingRangeValid) {
        return;
      }
    }

    String text = _textEditingController.text;
    int changeLen = text.length - _lastText.length;
    if (changeLen < 0) {
      int start = _textEditingController.selection.start;
      _textList.removeRange(start, start + changeLen.abs());
    } else {
      int start = _textEditingController.selection.start - changeLen;
      List<String> arr = text.substring(start, start + changeLen).split('');
      _textList.insertAll(start, List.generate(changeLen,
              (index) => TextBean(_color, arr[index])));
    }
    _lastText = text;
  }

  final int _width = 160;
  final int _height = 64;
  final List<int> _fontSizes = [
  ];
  int _fontSizeIndex = 0;

  int _frameIndex = 0;
  List<List<Color>> _frames = [];

  void _convert() async{
    if(Platform.isAndroid || Platform.isIOS){
      ColorResult result = await _textPixelPlugin.getTextColors(
          width: _width,
          height: _height,
          textList: _textList.map((e) => e.toValueMap).toList(),
          fontSize: _fontSizes[_fontSizeIndex],
          maxFrames: 3,
        maxLines: max(_height ~/ _fontSizes[_fontSizeIndex], 1),
        continuousPaint: false,
        horizontalCenter: true
      );
      List<int>? data = result.colors;
      if(data != null && data.isNotEmpty){
        int frameLen = _width * _height;
        List<List<Color>> colors = [];
        int len = data.length;
        print('frameLen $frameLen data.length ${data.length}');
        for(int i = 0; i < len; i += frameLen){
          colors.add(data.getRange(i, i + frameLen).map((e) => Color(e)).toList());
        }
        _frameIndex = 0;
        _frames = colors;
        _colorNotifier.maxLines = result.maxLines??0;
        _colorNotifier.colors = colors.first; // 预览第一帧
      }
    }
  }

  void _pickFontSize(BuildContext context){
    showCupertinoDialog(
        context: context,
        builder: (ctx) => _buildSelector(_fontSizes),
      barrierDismissible: true
    );
  }

  void _nextFrame(){
    if(_frames.length <= 1){
      return;
    }
    if(_frameIndex + 1 >= _frames.length){
      _frameIndex = 0;
    }else{
      _frameIndex += 1;
    }
    _colorNotifier.colors = _frames[_frameIndex];
  }

  void _lastFrame(){
    if(_frames.length <= 1){
      return;
    }
    if(_frameIndex - 1 < 0){
      _frameIndex = _frames.length - 1;
    }else{
      _frameIndex -= 1;
    }
    _colorNotifier.colors = _frames[_frameIndex];
  }

  @override
  void dispose() {
    _textEditingController.removeListener(_onInput);
    _textEditingController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Plugin example app'),
      ),
      body: SingleChildScrollView(
        child: Column(
          children: [
            SizedBox(
              width: double.infinity,
              height: MediaQuery.of(context).size.width,
              child: RepaintBoundary(
                child: CustomPaint(
                  painter: ColorPainter(
                      colorNotifier: _colorNotifier,
                      width: _width,
                      height: _height,
                    fontSize: _fontSizes[_fontSizeIndex],
                  ),
                ),
              ),
            ),
            TextField(
              controller: _textEditingController,
            ),
            TextButton(onPressed: _convert, child: const Text("convert")),
            TextButton(onPressed: (){
              _pickFontSize(context);
            }, child: Text("pick fontSize, current ${_fontSizes[_fontSizeIndex]}")),
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceEvenly,
              children: [
                TextButton(onPressed: _lastFrame, child: const Text("last frame")),
                TextButton(onPressed: _nextFrame, child: const Text("next frame")),
              ],
            ),
            Text('Running on: $_platformVersion\n'),
          ],
        ),
      ),
    );
  }

  Widget _buildSelector(List list) {
    FixedExtentScrollController controller =
    FixedExtentScrollController(initialItem: _fontSizeIndex);
    return Material(
      type: MaterialType.transparency,
      child: Center(
        child: Container(
          width: double.infinity,
          height: 400,
          color: Colors.white,
          child: CupertinoPicker.builder(
            scrollController: controller,
            itemExtent: 50,
            onSelectedItemChanged: (position) {
              setState(() {
                _fontSizeIndex = position;
              });
            },
            itemBuilder: (ctx, index) {
              return Center(child: Text('${list[index]}'));
            },
            childCount: list.length,
          ),
        ),
      ),
    );
  }
}
